ViVa: ViSta's Interactive Variable Application

ViVa, ViSta Interactive Variable Application, is an algebra-like language which calculates values for new variables and makes the variables available for further manipulation. 

ViVa consists of algebra-like expressions.  If the expression involves assignment to a variable, the variable is assigned the value of the expression, and the variable is saved for the duration of the session with ViSta. 

ViVa can be used in 3 ways. These ways are outlined briefly here. Examples of ViVa expressions are given below.

1) At the Listener, type a ViVa expression enclosed in brackets. For example, if x is a variable known to Lisp from, say, typing
   > (var x '(1 2 3)) 
   (1 2 3)
Then you can type the ViVa expression, in brackets, at the Lisp prompt:
   > [y = 2 + 3*x]
   (5 8 11)
The expression on the right side of the = sign is evaluated, the resulting value is assigned to y, and the value is returned. Thus:
   > [x=4.5]
   4.5
   > [y = 2 + 3*x]
   15.5

2) At the Listener, type a left bracket and a return. Lisp's > prompt is replaced by ViVa's ? prompt. Then you can type a series of ViVa expressions, each followed by a return. Each expression is evaluated when you type a return. Finally, type a right bracket to return to regular Lisp. The value of the last expression is returned. For example:
   > [
   ? s = list(2,4,6)
   (2 4 6)
   ? u = 3
   3
   ? v = 2
   2
   ? r = u + v*s
   (7 11 15)
   ? ]
   (7 11 15)
   > 

3) Enter a bracket enclosed ViVa statement in the middle of lisp. It is evaluated and returns its value to Lisp. Thus:
> (list 1 2 [sqrt(9)] 4)
(1 2 3.0 4)


LIMITATIONS: 
1) ViVa can only be entered from the Listener, not from files. Thus, ViVa scripts or applets are not possible.
2) When using ViVa, variable names cannot contain embedded characters interpreted as mathematical operators (i.e., - + = / *, etc). These signs are always interpreted as being a mathematical operator. In particular, the Lisp convention of variable or function names containing dashes, such as principal-components or normal-rand, is not allowed in ViVa. Underscores may be substituted for dashes (see next point). 
3) Underscores may only be used as a substitute for dashes (see previous point).

UNDERSCORES:
Since dashes are very commonly used in the names Lisp functions, you may substitute underscores for dashes. Thus, you can enter principal_components or normal_rand. ViVa will translate appropriately.

VERBOSE:
Type (viva-verbose t) or (viva-verbose nil) at the Lisp > prompt to control the ammount of output generated by ViVa.

VIVA EXPRESSIONS: 
ViVa expressions conform to a subset of the syntax for the C programming language. Specifically, ViVa supports all syntax defined in section 18.1 of the original Kernighan and Ritchie book, plus all C numerical syntax including floats and radix syntax (i.e. 0xnnn, 0bnnn, and 0onnn).  ViVa supports multiple array subscripts.

ABOUT VIVA AND PARCIL
ViVa uses PARCIL, copyright (c) 1992 by Erann Gat. Parcil is used under the terms of the GNU General Public License as published by the Free Software Foundation. PARCIL parses expressions in the C programming language into Lisp. ViVa then takes the parsed statements and creates an interactive environment in which they are evaluated. Thanks to Sandy Weisberg for providing Parcil.


ViVa EXAMPLES
 
Examples of each way of using ViVa are given below.

1) At the Listener, type a ViVa expression enclosed in brackets. It is evaluated and the value returned. If the expression involves assignment to a variable, the variable is assigned the value, and the variable is saved for the duration of the session. The variable can be entered into a data object, using the DATASET function, and then saved permanently.
   Here is an example:
    > [A = 2 + (3*4)]
    14
Here, the user has typed the ViVa expression A=2+(3*4) enclosed in brackets. ViSta responds with 14, the appropriate value, using the standard rules of operator precedence. A new Lisp variable A has been created:
    > a
    14
    > 
You can retrieve the list of all saved variables created by ViVa by typing
    > $viva-vars
These variables, and those created by the VAR function, are free variables (not in a data object). You can get a list of all free variables by typing:
    > $free-vars
You can also retrieve the list of all variables in all data objects by typing:
    > $data-vars
Note that any Lisp function may be used in ViVa expressions, though in standard algrebraic syntax. For example:
    > [a=3*iseq(4)]
    (0 3 6 9)
where iseq(4) is the ViVa equivalent of Lisp's (iseq 4), which generates the sequence of numbers (0 1 2 3). 

These functions can use any $data-vars as arguments:
    > [b=a^2]
    > (0 9 36 81)
A Lisp expression involving a function with multiple arguments is written as a ViVa function involving arguments that are comma-delimited. Thus
    > [L=list(1,2,3)]
corresponds to the Lisp expression (setf L (list 1 2 3)).
Note that a ViVa expression may be a compound expression:
    > { ( x=1,y=2,print(x+y),sin(pi/2) ) }
    3 
    1.0
    > x
    1
    > y
    2
    >

2) At the Listener, type a left bracket and a return. Lisp's > prompt is replaced by ViVa's ? prompt. Then you can type a series of ViVa expressions, each being evaluated when you type a return. Finally, type a right bracket to return to regular Lisp. Notice that functions with multiple arguments have their arguments separated by commas. Also, notice that vector and matrix algebra are supported. Here is an example interaction:

    > [
    ? 2+3
    5
    ? a
    (0 3 6 9)    ;this value for A is left from above
    ? a=2+3
    5
    ? a          ;a new value for A has been defined
    5
    ? b=sqrt(a)
    2.23606797749979
    ? a=iseq(4)  ;yet another value for A
    (0 1 2 3)
    ? b=sqrt(a)  ;vector arithmetic is supported
    (0.0 1.0 1.4142135623730951 1.7320508075688772)
    ? ]          ;the value of the last expression is returned
    (0.0 1.0 1.4142135623730951 1.7320508075688772)
    > 

If you do not wish to see so much output, type:
    [viva_verbose=not(t)]
For example:
    > [viva_verbose=not(t)
    ? a=normal_rand(10)
    ? b=a^2
    ? c=iseq(10)
    ? d=c*b
    ? ]
    (0.0 0.12086435903614712 0.12465600120144842 0.05113395472276512 0.8572483580685174 2.8192853102290143 8.009152301820079 33.31659449692597 0.9436767853187026 1.1345846087676839)
    > d
(0.0 0.12086435903614712 0.12465600120144842 0.05113395472276512 0.8572483580685174 2.8192853102290143 8.009152301820079 33.31659449692597 0.9436767853187026 1.1345846087676839) 
    > 
   Lisp's matrix language may be used with ViVa. Here is an example:
   ?a=matrix ( list(2,2), list(1, 2 ,3 ,4))
   #2A((1 2) (3 4))
   ?b=matrix ( list(2,3), list(1,2,3,4,5,6))
   #2A((1 2 3) (4 5 6))
   ?c=matmult(a,b)
   #2A((9.0 12.0 15.0) (19.0 26.0 33.0))

3) Enter a bracket enclosed ViVa statement in the middle of lisp. It is evaluated and returns its value to Lisp:
     
   >(list 1 3 [sqrt(25)] 7)
   (1 3 5.0 7)

   
TWO EXAMPLES
The first example involves calculating points in an Introductory Statistics course. The data are in P3099pts.lsp datafile. You can open these data with the OPEN DATA menu item in the FILE menu. In this example, ViVa is used to create variables, then the DATASET function is used to create a data object from them.
[
? homework_sum=homework1+homework2=homework3
(12.0 14.24 13.399999999999999 13.11 15.36 12.96 12.22 13.82 14.31 13.09 13.98 13.67 7.45 15.33 12.1 12.92 5.57)
? total=homework_sum+midterm1
(170.0 173.24 168.4 189.11 197.36 119.96 159.22 135.82 194.31 189.09 197.98 189.67 159.45 194.33 153.1 176.92 173.57)
? ]
(170.0 173.24 168.4 189.11 197.36 119.96 159.22 135.82 194.31 189.09 197.98 189.67 159.45 194.33 153.1 176.92 173.57)
> (dataset summary homework_sum total)
#<Object: a9e82c, prototype = MV-DATA-OBJECT-PROTO>
>

The second example involves calculating grades from points earned during the course.

(load (strcat *data-dir-name* "p3099pts.lsp"))
                
[homeworksum = homework1 + homework2 + homework3] 
[midpts = homeworksum + midterm1]

(let ((grades (mapcar #'(lambda (pts)
          (cond ((> pts 190) "A")
                ((< 170 pts 190) "B")
                ((< 150 pts 170) "C")
                ((< 140 pts 150) "C-")
                ((<   0 pts 150) "D")))
                            midpts))))

(dataset homework1 homework2 homework3 homeworksum
         midterm1 midpts grades)
